﻿#include<stdio.h>
#include<stdlib.h>
#include"state.h"
/*
 * ----------Stack----------
 */
Status initStack(Stack *s, int size){
	s->base = (SElemType *)malloc(size * sizeof(SElemType));
	if(!s->base)	exit(OVERFLOW);
	s->top = s->base;
	s->stacksize = size;
	return OK;
}
Status getTop(Stack *s, SElemType *e){
	if(s->top == s->base)	return ERROR;
	*e = *(s->top-1);
	return OK;
}
Status push(Stack *s, SElemType e){
	*s->top++ = e;
	return OK;
}
Status pop(Stack *s, SElemType *e){
	if(s->base == s->top)	return ERROR;
	*e = *--s->top;
	return OK;
}
Status stackEmpty(Stack s){
	if(s.base == s.top)	return 1;
	else return 0;
}
int stackLength(Stack s){
	return (s.top - s.base);
}
Status clearStack(Stack *s){
	s->top = s->base;
	return OK;
}
Status fullStack(Stack s){
	if(s.top - s.base == s.stacksize)	return 1;
	else return 0;
}
/*
 * ----------Stack----------
 */
Status initq(LQ *q){
	q->front = q->rear = (QP)malloc(sizeof(QN));
	if(!q->front)	exit(OVERFLOW);
	q->front->next = NULL;
	return OK;
}
Status dstrq(LQ *q){
	while(q->front){
		q->rear = q->front->next;
		free(q->front);
		q->front = q->rear;
	}return OK;
}
Status enq(LQ *q, QElemType e){
	QN *p;
	p = (QP)malloc(sizeof(QN));
	if(!p)	exit(OVERFLOW);
	p->data = e;
	p->next = NULL;
	q->rear->next = p;
	q->rear = p;
	return OK;
}
Status delq(LQ *q, QElemType *e){
	QN *p;
	if(q->front == q->rear)	return(ERROR);
	p = q->front->next;
	*e = p->data;
	q->front->next = p->next;
	if(q->rear == p)	q->rear = q->front;
	free(p);
	return OK;
}
/*
 * ----------other----------
 * rs(), Deal the input like ('D',12,32),('A',14,56),('E',0,0)
 * carIn(), when the type is 'A', it will be executed
 * carOut(), when the type is 'D', it will be executed
 * error(),
 * showStop(), Show cars in the parking lot
 * showSidewalk(), Show cars in the sidewalk
 */
void rs(char *b, int price){
	char act,no[10],*p,*q;
	int i,num,time;
	p=b;
	while(*p != '\0'){
		if((*(p++) != '(') || (*(p++) != '\'') || (*p != 'A'&&*p != 'D' && *p != 'E')){
			error(2);return;
		}act = *p++;
		if(*(p++) != ('\'') || *(p++) != ','){
			error(2);return;
		}q = p;
		while(*p != ',')	p++;
		if(p == q || (p-q) > MAX_NUMBER_LENGTH)	{
			error(1);return;
		}	i = 0;
		while(p != q){
			no[i] = *q; i++, q++;
		}no[i] = '\0';
		num = atoi(no);
		*q++; p = q;
		while(*p != ')')	p++;
		if(p == q || (p-q) > MAX_NUMBER_LENGTH){
			error(1); return;
		}i = 0;
		while(p != q){
			no[i] = *q; i++, q++;
		}no[i] = '\0';
		time = atoi(no);
		if(act == 'E')	return;
		if(*(++p) == ',')	p++;
		if(act == 'A')	carIn(num, time);
		else if(act == 'D')carOut(num, time, price);
	}
}
void carIn(int num,int time){
	car tcar;
	tcar.plate = num;
	tcar.time = time;
	if(fullStack(stop)){
		printf("Parking lot is full! \n");
		enq(&sidewalk, tcar);
		printf("Car %d will stop in sidewalk at %d .\n\n", num, time);
	}else{
		push(&stop, tcar);
		printf("Car %d will stop in parking lot at %d, position: %d . \n\n", num, time, stackLength(stop));
	}
}
void carOut(int num, int time, int price){
	car tcar;
	int tag = 0;
	tcar.plate = '-1';
	while(stop.top != stop.base){
		pop(&stop, &tcar);
		if(tcar.plate == num)	break;
		push(&tmp, tcar);
	}
	if(tcar.plate != num)	{
		tag = 1;
		printf("No car %d in the parking lot!\n\n", num);
	}else{
		printf("Car %d drives away at %d, it entered at %d.\n", num, time,tcar.time);
		printf("Price: %d\n\n", price*(time - tcar.time));
	}
	while(tmp.top != tmp.base){
		pop(&tmp, &tcar);
		push(&stop, tcar);
	}
	if(tag != 1){
		if(sidewalk.front != sidewalk.rear){
			delq(&sidewalk, &tcar);
			tcar.time = time;
			push(&stop, tcar);
			printf("Car %d enter the parking at %d ,position: %d.\n\n", tcar.plate, tcar.time, stackLength(stop));
		}
	}
}
void error(int tag){
	switch(tag){
		case 1:	printf("Format error, maybe a unimaginable long number or null!\n\n");break;
		case 2: printf("Format error, maybe a unimaginable char or string!\n\n");break;
	}
}
void showStop(){
	SElemType *car;
	int i = 1;
	if(stackEmpty(stop)){
		printf("No car in the parking lot!\n\n");
		return;
	}car = stop.base;
	while(car != stop.top){
		printf("Car %d enter at %d ,position: %d\n", car->plate, car->time, i++);
		car++;
	}printf("\n");
}
void showSidewalk(LQ q){
	QN *ph;
	if(q.front == q.rear){
		printf("No car in the sidewalk!\n\n");
		return;
	}ph = q.front->next;
	while(ph != q.rear->next){
		printf("Car %d enter the sidewalk at %d\n", ph->data.plate, ph->data.time);
		ph = ph->next;
	}printf("\n");
}